﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using FarseerPhysics.Factories;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Common;
using FarseerPhysics.Common.Decomposition;
using FarseerPhysics.Collision.Shapes;
using FarseerPhysics.Common.PolygonManipulation;
using FarseerPhysics.Collision;

namespace eTech_Physics_Sandbox
{
    class DrawableLine
    {
        List<LineSegment> lineSegments = new List<LineSegment>();
        List<Vector2> vertices = new List<Vector2>();
        Vector2 lastWorldPosition, worldPosition;

        public List<LineSegment> Segments
        {
            get { return lineSegments; }
        }

        Texture2D _lineTexture;
        Texture2D _cornerTexture;

        Body body;

        /*
         * This class is used to create and draw varing shapes, using the line segment texture.
         * It is given points in a List, and creates a line from them.
         */
        public DrawableLine(List<Vector2> vertices, Texture2D lineTexture, Texture2D cornerTexture)
        {
            _lineTexture = lineTexture;
            _cornerTexture = cornerTexture;
            this.vertices = vertices;
            for(int i = 0; i < vertices.Count; i++) //Loop through each of the vectors, getting distance between them.
            {
                if (i > 0)
                {
                    Vector2 lastVertex = vertices[i - 1];
                    Vector2 vertex = vertices[i];

                    if (lastVertex != Vector2.Zero)
                        lineSegments.Add(new LineSegment(new Vector2[] { lastVertex, vertex }));

                    lastVertex = vertex;
                }
                
            }
        }

        public DrawableLine(Texture2D lineTexture, Texture2D cornerTexture)
        {
            _lineTexture = lineTexture;
            _cornerTexture = cornerTexture;
        }

        public void addVertex(Vector2 vertex)
        {
            if (vertices.Count > 0)
            {
                Vector2 lastVertex = vertices[vertices.Count - 1];
                lineSegments.Add(new LineSegment(new Vector2[] { lastVertex, vertex }));
            }

            vertices.Add(vertex);
            
        }

        public void Update(GameTime gameTime) //TODO: Physics updates -NTR
        {
            //for (int i = 0; i < lineSegments.Count; i++)
            //{
            //    lineSegments[i].Update(gameTime);
            //}
            if (body != null)
            {
                worldPosition = ConvertUnits.ToPixels(body.Position);
                Vector2 dwp = worldPosition - lastWorldPosition;
                if (body.FixtureList.Count > 0)
                {
                    PolygonShape shape = (PolygonShape)body.FixtureList[0].Shape;
                    Vertices vert = shape.Vertices;
                    for (int i = 0; i < vert.Count; i++)
                    {
                        Vector2 v = vert[i];
                        v = ConvertUnits.ToPixels(v);
                        vertices[i] = v;
                    }
                }
               

                lastWorldPosition = worldPosition; 
            }


        }

        public void Draw(SpriteBatch spriteBatch)
        {
            //for (int i = 0; i < lineSegments.Count;i++ )
            //{
            //    LineSegment segment = lineSegments[i];
            //    segment.Draw(spriteBatch, _lineTexture, Vector2.Zero);
            //    spriteBatch.Draw(_cornerTexture, segment.EndPoints[0], null, Color.White, 0f, new Vector2(_cornerTexture.Width / 2, _cornerTexture.Height / 2), 1f, SpriteEffects.None, 0f);
            //}
            
            DrawLine.DrawPolygon(spriteBatch, vertices.ToArray(), vertices.Count, Color.White, 10);

            
        }

        public void Finish(World world, Vector2 mousePos)
        {
            Vertices vert = new Vertices();
            for (int i = 0; i < vertices.Count; i++)
            {
                //Vector2 v2 = new Vector2(v.X + 5, v.Y - 5); ILL FIX THIS FINE -NTR
                vert.Add(ConvertUnits.ToMeters(vertices[i]));
            }
            List<Vertices> vertlist = FlipcodeDecomposer.ConvexPartition(vert);
            //body = BodyFactory.CreateCompoundPolygon(world, vertlist, 1f, ConvertUnits.ToMeters(vertices[0]));
            body = BodyFactory.CreateBody(world);
            body.BodyType = BodyType.Dynamic;
            FixtureFactory.AttachCompoundPolygon(vertlist, 1f, body);
            lastWorldPosition = ConvertUnits.ToPixels(body.Position);
        }
    }
}
